/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gtugs.web;

import de.micromata.opengis.kml.v_2_2_0.Coordinate;
import de.micromata.opengis.kml.v_2_2_0.Document;
import de.micromata.opengis.kml.v_2_2_0.Folder;
import de.micromata.opengis.kml.v_2_2_0.Icon;
import de.micromata.opengis.kml.v_2_2_0.IconStyle;
import de.micromata.opengis.kml.v_2_2_0.Kml;
import de.micromata.opengis.kml.v_2_2_0.Placemark;
import de.micromata.opengis.kml.v_2_2_0.Point;
import de.micromata.opengis.kml.v_2_2_0.Style;

import org.gtugs.domain.Chapter;
import org.gtugs.domain.User;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.web.servlet.View;

import java.io.PrintWriter;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author van@gtugs.org (Van Riper)
 */
class KmlMapView implements View, MessageSourceAware {
  public static final String MODEL_DATA_KEY = "chaptersGroupedByCountry";
  public static final String KML_MIMETYPE ="application/vnd.google-earth.kml+xml";

  private MessageSource messageSource;

  @Override
  public void setMessageSource(MessageSource messageSource) {
    this.messageSource = messageSource;
  }

  /**
   * Default MIME type. At this point, there is no way to know if jsonP should be used.
   */
  public String getContentType() {
    return KML_MIMETYPE;
  }

  public void render(Map model, HttpServletRequest request,
      HttpServletResponse response) {
    try {
      response.setContentType(getContentType());
      PrintWriter out=response.getWriter();
      @SuppressWarnings("unchecked")
      final List<List<Chapter>> chaptersGroupedByCountry =
          (List<List<Chapter>>) model.get(MODEL_DATA_KEY);

      final Kml kml = new Kml();
      Document doc = kml.createAndSetDocument()
          .withName("Google Technology User Groups")
          .withOpen(true);

      Icon icon = new Icon();
      icon.setHref("http://maps.google.com/mapfiles/ms/icons/green-dot.png");
      IconStyle iconStyle = new IconStyle();
      iconStyle.setIcon(icon);
      iconStyle.setScale(1.0);
      Style style = doc.createAndAddStyle();
      style.setIconStyle(iconStyle);
      style.setId("active");

      icon = new Icon();
      icon.setHref("http://maps.google.com/mapfiles/ms/icons/yellow-dot.png");
      iconStyle = new IconStyle();
      iconStyle.setIcon(icon);
      iconStyle.setScale(1.0);
      style = doc.createAndAddStyle();
      style.setIconStyle(iconStyle);
      style.setId("incubating");

      for (List<Chapter> chaptersForOneCountry : chaptersGroupedByCountry) {
        final String country = chaptersForOneCountry.get(0).getCountry();
        Folder folder = doc.createAndAddFolder();
        folder.setName(country);
        folder.setOpen(false);
        for (Chapter chapter : chaptersForOneCountry) {
          Placemark placemark = folder.createAndAddPlacemark();
          placemark.setName(chapter.getName());
          placemark.setDescription(buildPlacemarkDescription(chapter));
          Point point = placemark.createAndSetPoint();
          List<Coordinate> coordinates = point.createAndSetCoordinates();
          coordinates.add(new Coordinate(chapter.getLongitude(), chapter.getLatitude()));
          if ("active".equalsIgnoreCase(chapter.getStatus())) {
            placemark.setStyleUrl("#active");
          } else {
            placemark.setStyleUrl("#incubating");
          }
        }
      }

      kml.marshal(out);

    } catch (java.io.IOException e) {
      // TODO(vanriper): log or otherwise handle IO exceptions.
    }
  }

  private String buildPlacemarkDescription(Chapter chapter) {
    StringBuilder buf = new StringBuilder(2048);

    String[] headerArgs = {
        getChapterAdmins(chapter),
        chapter.getWebsite()
    };
    String header = messageSource.getMessage("kml.description.header", headerArgs, Locale.getDefault());
    buf.append(header);

    String expandedDescription = chapter.getDescription().replaceAll(
        "<p><a href=\"https?://www\\.youtube\\.com/watch\\?v=([^\"]+)\">(.+)</a></p>",
        messageSource.getMessage("kml.youtube.embed", null, Locale.getDefault())
    );
    expandedDescription = expandedDescription.replaceAll(
        "<p><a href=\"([^\"]+)\">Photo:(.+)</a></p>",
        messageSource.getMessage("kml.photo.embed", null, Locale.getDefault())
    );
    buf.append(expandedDescription);
    
    return buf.toString();
  }

  private String getChapterAdmins(Chapter chapter) {
    StringBuilder result = new StringBuilder(512);

    boolean firstUser = true;
    List<User> admins = chapter.getAdministrators();
    for (User u : admins) {
      if (firstUser) {
        firstUser = false;
      } else {
        result.append(", ");
      }
      result.append(u.getName());
    }

    return result.toString();
  }
}
